﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Reflection;

namespace mrp16062010.Rota
{
    [Serializable()]
    class RotaParcasi : AbstractRota, ISerializable
    {
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        

        private Stok stok;
        public string Tanim;
        public int StokKodu;

        public Stok Stok
        {
            get { return stok; }
            set { stok = value; }
        }

        private int adet = 1;

        public int Adet
        {
            get { return adet; }
            set { adet = value; }
        }



        public int ToplamUretilecekAdet(int siparisAdet)
        {
            return UretilecekAdet(siparisAdet);
        }

        //private int siparisAdedi;

        //public int SiparisAdedi
        //{
        //    get { return siparisAdedi; }
        //    set { siparisAdedi = value; }
        //}



        public int UretilecekAdet(int siparisAdet)
        {
            int toplamUretilecekAdet = 0;
            if (this.ust == null)
            {
                toplamUretilecekAdet = siparisAdet * adet;
                return toplamUretilecekAdet;
            }
            toplamUretilecekAdet = this.Ust.Rota.UretilecekAdet(siparisAdet) * this.adet;
            return toplamUretilecekAdet;
        }

        //private TimeSpan toplamUzunluk;

        //public TimeSpan ToplamUzunluk
        //{
        //    get { return toplamUzunluk; }
        //}


        private List<Rota.Operasyon> operasyonList = new List<Operasyon>();

        public List<Rota.Operasyon> OperasyonList
        {
            get { return operasyonList; }
            set { operasyonList = value; }
        }
        private Rota.Operasyon ust;

        public Rota.Operasyon Ust
        {
            get { return ust; }
            set { ust = value; }
        }

        public RotaParcasi(Stok gelenStok, int gelenAdet)
        {
            Stok = gelenStok;
            adet = gelenAdet;
        }
        //Eklenen operasyonun listede bir sırası var. 0 dan başlar ve devam eder.
        public void OperasyonEkle(Rota.Operasyon gelen)
        {
            OperasyonList.Add(gelen);
            gelen.Rota = this;
            gelen.Sira = OperasyonList.Count - 1;//Önce eklendiği için liste 1 artmış olacağından 1 çıkardık
        }
        //Burada rotaparçasının yukarıdan itibaren 0dan başlayarak uzunluğunu dallara doğru topluyoruz.
        //Bulunduğu konuma kadar, bulunduğu konum dahil olmak üzere, toplam zamanı döndürür
        public TimeSpan Uzunluk(Rota.AbstractRota UstLimit, int siparisAdet)
        {
            TimeSpan uzunluk = new TimeSpan();
            foreach (Rota.Operasyon item in this.OperasyonList)
            {
                uzunluk += TimeSpan.FromTicks(item.Sure.Ticks * this.ToplamUretilecekAdet(siparisAdet));
                uzunluk = uzunluk + item.HazirlikSuresi;
                /*if (item==UstLimit)
                {
                    return uzunluk;
                }*/
            }

            if (this.Ust != null && this != UstLimit)
            {
                uzunluk += this.Ust.Rota.Uzunluk(UstLimit, siparisAdet);
            }
            //this.toplamUzunluk = uzunluk;
            return uzunluk;
        }
        //Burada en alttaki dalları buluyoruz ve liste şeklinde döndürüyoruz
        private bool SonDalMi()
        {

            if (operasyonList.Count == 0)
            {
                return true;
            }
            else
            {
                foreach (Rota.Operasyon op in operasyonList)
                {
                    if (op.AltParca.Count > 0)
                    {
                        return false;
                    }
                }
            }
            return false;
        }

        public List<Rota.RotaParcasi> SonDallar(Rota.RotaParcasi parca)
        {
            List<Rota.RotaParcasi> meyveler = new List<Rota.RotaParcasi>();
            if (parca.SonDalMi())
            {
                meyveler.Add(parca);
            }
            else
            {
                foreach (Rota.Operasyon op in parca.operasyonList)
                {
                    if (op.AltParca.Count > 0)
                    {
                        foreach (Rota.RotaParcasi rp in op.AltParca)
                        {
                            meyveler.AddRange(SonDallar(rp));
                        }
                    }
                }
            }
            //Uzundan kısaya doğru sırala

            return meyveler;
        }

        public Rota.RotaParcasi EnUzunDal()
        {
            List<Rota.RotaParcasi> meyveler = (from x in SonDallar(this)
                                               orderby x.Uzunluk(this, 1) descending
                                               select x).ToList<Rota.RotaParcasi>();
            return meyveler.First();
        }

        public int Seviye()
        {
            int seviye = 0;
            if (this.Ust != null)
            {
                seviye++;
                seviye += this.Ust.Rota.Seviye();
            }
            return seviye;
        }

        private Tarih rotaTarih;

        public Tarih RotaTarih
        {
            get { return rotaTarih; }
            set { rotaTarih = value; }
        }

        public RotaParcasi(SerializationInfo info, StreamingContext ctxt)
            : base(info, ctxt)
        {
            Serialize.InfoCopier.Read(info, this);
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info = Serialize.InfoCopier.Write(info, this);
        }

        [NonSerialized]
        private List<SiralamaBilgileri> tumSiralamalar;

        public List<SiralamaBilgileri> TumSiralamalar
        {
            get { return tumSiralamalar; }
            set { tumSiralamalar = value; }
        }
        
    }
}
